package __examples

import (
	"context"
	"fmt"
	"math/rand"
	"sort"
	"time"
)

/************* 自定义排序 **************/

// ByLength 字符串数组，其方法不需要用指针
// 需要实现 Interface 接口
type ByLength []string

// Less 定义比较方式
// 这里用长度比较，长度小的放前面
func (b ByLength) Less(i, j int) bool {
	return len(b[i]) < len(b[j])
}

// Swap 定义交换方式
func (b ByLength) Swap(i, j int) {
	b[i], b[j] = b[j], b[i]
}

// Len 数组长度
func (b ByLength) Len() int {
	return len(b)
}

// 自定义排序
func sortByFunction() {
	bl := ByLength{"admin", "bgm", "cd"}
	sort.Sort(bl)
	//fmt.Println(bl)
}

/************* Recover and Panic **************/

func RecAndPan() {
	// 捕获代码抛出的异常
	defer func() {
		recover()
	}()
	myPro()
	// 下面的代码不会执行
	fmt.Println("after problem")
}

func myPro() {
	//panic()
}

/************* Random **************/

func randNum(seed int64) {
	rand.Seed(seed)
	fmt.Println(rand.Intn(100))
	fmt.Println(rand.Intn(100))
	fmt.Println(rand.Intn(100))
}

/************* Context **************/

func ContextExample() {
	// 用途之一：在各个协程之间传递消息，尤其是主动通知停止
	// with有几个函数，WithCancel用于取消
	ctx, cancel := context.WithCancel(context.Background())
	go worker(ctx, "job1")
	go worker(ctx, "job2")
	go worker(ctx, "job3")
	time.Sleep(time.Second * 3)
	cancel()
	time.Sleep(time.Second * 1)
}

func worker(ctx context.Context, name string) {
	for {
		select {
		// 等待context的结束消息
		case <-ctx.Done():
			fmt.Printf("%s is done\n", name)
			return
		default:
			fmt.Printf("%s is working\n", name)
			time.Sleep(time.Second)
		}
	}
}
